package cate.game.activity.loopfund;

import cate.common.table.d.GDFunc;
import cate.common.table.d.GDOperation;
import cate.common.table.pay.PayItemRow;
import cate.common.table.trademall.loopmonthfund.LoopMonthFundCommonRow;
import cate.common.table.trademall.loopmonthfund.LoopMonthFundItemRow;
import cate.common.util.GameResult;
import cate.game.activity.base.core.RoleActivitySingle;
import cate.game.activity.loopfund.msg.LoopMonthFundInfoResp;
import cate.game.chat.ChatContentParam;
import cate.game.mail.po.MailBuilder;
import cate.game.res.MixRes;
import cate.game.res.MixResAdder;
import cate.game.role.Role;
import cate.game.role.mail.Mail;
import easy.java.dev.note.NoteField;
import easy.java.practice.errorcode.EcResult;

import java.util.*;

public class LoopMonthFundActivity extends RoleActivitySingle {
    @NoteField(value = "是否已激活")
    public boolean active;
    @NoteField(value = "已领取的奖励ID列表")
    public Map<Integer, Boolean> gotMap;

    @Override
    public void initialize(Role role) {
        super.initialize(role);
        if (gotMap == null) {
            gotMap = new HashMap<>();
        }
    }


    @Override
    public void onDaySpan(boolean silence) {
        super.onDaySpan(silence);
    }

    /**
     * 获取目前组配置
     *
     * @return 配置Row
     */
    public final LoopMonthFundCommonRow findCurGroupConfigRow() {
        return role.getGame().table.tradeMall.loop_month_fund_common.get(configTid());
    }


    /**
     * 获取当前基金天数
     *
     * @return 当前天数
     */
    public final int curDay() {
        return getCurrentDay();
    }

    /**
     * 同步信息到前端
     */
    public void noticeUpdate() {
        role.sendNow(new LoopMonthFundInfoResp(this));
    }

    /**
     * 是否允许购买
     *
     * @param pir 配置row
     * @return 校验结果
     */
    public GameResult<Void> allowPay(PayItemRow pir) {
        int tid = pir.funcSubId;
        GameResult<Void> r = new GameResult<>();
        if (configTid() != tid) {
            return r.fail("非当期基金");
        }
        if (active) {
            return r.fail("基金已激活");
        }
        LoopMonthFundCommonRow configRow = findCurGroupConfigRow();
        if (configRow == null) {
            return r.fail("基金不存在");
        }
        if (pir.price == configRow.price) {
            if (getCurrentDay() <= configRow.discoutDay) {
                return r.fail("请使用优惠价购买");
            }
        } else if (pir.price == configRow.discountPrice) {
            if (getCurrentDay() > configRow.discoutDay) {
                return r.fail("优惠已过期");
            }
        } else {
            return r.fail("价格不对");
        }
        if (configRow.needMonthCard == 1) {
            if (!role.getPay().tradeMall.monthCard.existActiveMonthCard()) {
                return r.fail(902101, "请先购买至尊月卡");
            }
        }
        return r.success();
    }

    /**
     * 激活基金
     */
    public void onPaySuccess(PayItemRow pir) {
        if (active) {
            return;
        }
        active = true;
        LoopMonthFundCommonRow configRow = findCurGroupConfigRow();
        if (configRow != null) {
            if (pir.price == configRow.price) {
                if (getCurrentDay() <= configRow.discoutDay) {
                    return;
                }
            } else if (pir.price == configRow.discountPrice) {
                if (getCurrentDay() > configRow.discoutDay) {
                    return;
                }
            } else {
                return;
            }

            MixRes mailRes = new MixRes(configRow.activeRewardStr);
//            if (!mailRes.isEmpty()) {
//                Mail activeMail = new MailBuilder()
//                        .setContentId(configRow.activeMailId)
//                        .setReward(mailRes)
//                        .build();
//                role.getGame().mail.send(role, activeMail);
//            }
            mailRes.addAndDialog(role, true, findOperation(), pir.funcSubId);

            if (configRow.lampId != 0) {
                List<ChatContentParam> params = new ArrayList<>();
                params.add(ChatContentParam.c(role.getBase().name));
                role.getGame().notice.lampOnline(role, configRow.lampId, params);
            }
        }
        noticeUpdate();
    }

    /**
     * 基金过期
     */
    public void onFundOverdue() {
        if (active) {
            LoopMonthFundCommonRow commonConfig = findCurGroupConfigRow();
            if (commonConfig == null) {
                logger.error("[LoopMonthFundPO] 配置缺失! ID=%d", configTid());
                return;
            }
            // 检测是否需要补发奖励邮件
            MixRes mixRes = new MixRes();
            for (Map.Entry<Integer, Boolean> entry : gotMap.entrySet()) {
                if (!entry.getValue()) {
                    LoopMonthFundItemRow configRow = role.getGame().table.tradeMall.loop_month_fund_item.get(entry.getKey());
                    if (configRow != null) {
                        mixRes.addList(new MixRes(configRow.rewardStr));
                    }
                }
            }
            // 有未领取的奖励
            if (!mixRes.isEmpty()) {
                Mail overdueMail = new MailBuilder()
                        .setContentId(commonConfig.overdueMailId)
                        .setReward(mixRes)
                        .build();
                role.getGame().mail.send(role, overdueMail);
            }
            role.getRes().expireNotice.addFunc(GDFunc.TRADE_MALL_LOOP_MONTH_FUND);
        }
        gotMap.clear();
    }


    /**
     * 领取月循环基金奖励
     *
     * @param configId 配置ID
     * @return 领奖结果 无携带数据
     */
    public GameResult<LoopMonthFundActivity> onReceiveLoopMonthFundReward(int configId) {
        GameResult<LoopMonthFundActivity> r = new GameResult<>();
        r.data = this;
        if (!active) {
            return r.fail("基金未激活");
        }
        if (!gotMap.containsKey(configId)) {
            return r.fail("奖励不存在");
        }
        if (gotMap.get(configId)) {
            return r.fail("奖励已领取");
        }
        LoopMonthFundItemRow configRow = role.getGame().table.tradeMall.loop_month_fund_item.get(configId);
        if (configRow == null) {
            return r.fail("奖励不存在");
        }
        int curDay = curDay();
        if (curDay < configRow.day) {
            return r.fail("奖励未解锁");
        }
        // 发放奖励
        MixRes mixRes = new MixRes(configRow.rewardStr);
        EcResult<?> r_res = new MixResAdder().setRes(mixRes)
                .setOperation(findOperation())
                .setOperationSub(configId)
                .setDialogReward(true)
                .exe(role);
        if (!r_res.ok()) {
            return r.fail(r_res.message);
        }
        // 发放成功 添加领取标记
        gotMap.put(configId, true);
        return r.success();
    }

    /**
     * 一键领取奖励
     *
     * @return 领取结果 无携带数据
     */
    public GameResult<LoopMonthFundActivity> oneClickReceiveReward() {
        GameResult<LoopMonthFundActivity> r = new GameResult<>();
        r.data = this;
        if (!active) {
            return r.fail("基金未激活");
        }
        MixRes totalRes = new MixRes();
        List<Integer> keys = new LinkedList<>();
        gotMap.forEach((key, value) -> {
            if (value) {
                return;
            }
            LoopMonthFundItemRow configRow = role.getGame().table.tradeMall.loop_month_fund_item.get(key);
            if (configRow == null) {
                return;
            }
            int curDay = curDay();
            if (curDay < configRow.day) {
                return;
            }
            keys.add(key);
            totalRes.addList(new MixRes(configRow.rewardStr));
        });
        if (totalRes.isEmpty()) {
            return r.fail("无可领取奖励");
        }
        EcResult<?> r_res = new MixResAdder().setRes(totalRes)
                .setOperation(findOperation())
                .setOperationSub(0)
                .setDialogReward(true)
                .exe(role);
        if (!r_res.ok()) {
            return r.fail(r_res.message);
        }
        keys.forEach(itemId -> gotMap.put(itemId, true));
        return r.success();
    }

    public int findOperation() {
        switch (funcId()) {
            case GDFunc.TRADE_MALL_LOOP_MONTH_FUND:
                return GDOperation.TRADE_MALL_LOOP_MONTH_FUND;
            case GDFunc.TRADE_MALL_LOOP_MONTH_FUND_CHEAP:
                return GDOperation.TRADE_MALL_LOOP_MONTH_FUND_CHEAP;
            default:
                return GDOperation.NULL;
        }
    }

    @Override
    public void onRoleOpen() {

    }

    @Override
    public void onRoleEnd() {
        if (active) {
            onFundOverdue();
        }
        active = false;
        gotMap.clear();
    }

    @Override
    public void initSend() {
        noticeUpdate();
    }

    @Override
    public void excelCheck() {
        LoopMonthFundCommonRow commonRow = findCurGroupConfigRow();
        if (commonRow == null) {
            return;
        }
        gotMap.entrySet().removeIf(entry -> role.getGame().table.tradeMall.loop_month_fund_item.get(entry.getKey()) == null);
        for (LoopMonthFundItemRow configRow : role.getGame().table.tradeMall.loop_month_fund_item.getList()) {
            if (configRow.fundGroup != commonRow.fundGroup) {
                continue;
            }
            if (!gotMap.containsKey(configRow.id)) {
                gotMap.put(configRow.id, false);
            }
        }
    }
}
